package com.meefo.meeting.persistence.service.impl;

import com.meefo.meeting.common.CacheManager;
import com.meefo.meeting.common.DateTools;
import com.meefo.meeting.common.GUID2;
import com.meefo.meeting.common.Md5Util;
import com.meefo.meeting.config.Constants;
import com.meefo.meeting.persistence.bean.*;
import com.meefo.meeting.persistence.mapper.KeyMapper;
import com.meefo.meeting.persistence.mapper.MeetingFileMapper;
import com.meefo.meeting.persistence.mapper.MeetingInfoMapper;
import com.meefo.meeting.persistence.mapper.SignInfoMapper;
import com.meefo.meeting.persistence.service.MeetingService;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("meetingService")
public class meetingServiceImpl implements MeetingService {
    @Autowired
    MeetingInfoMapper meetingInfoMapper;
    @Autowired
    MeetingFileMapper fileMapper;
    @Autowired
    SignInfoMapper signInfoMapper;
    @Autowired
    KeyMapper keyMapper;
    public MeetingInfo getMeetingById(String meeting_id){
        MeetingInfo meetingInfo=meetingInfoMapper.selectByPrimaryKey(meeting_id);
        return meetingInfo;
    }

    public void updateQrCode(MeetingInfo meetingInfo) {
        meetingInfoMapper.updateByPrimaryKeySelective(meetingInfo);
    }

    @Transactional
    public Boolean saveMeeting(String subject,String content,String place,
                            String start_date,String meeting_period,String mtType,Integer attendance_people,
                            Float meeting_money,String is_net_meeting,String apply_unit,String apply_unit_name,
                            String apply_user,String apply_user_name){
        Boolean flag=true;

        //设置参数
        if(StringUtils.isEmpty(subject)||StringUtils.isEmpty(content)||StringUtils.isEmpty(place)||
                StringUtils.isEmpty(start_date)||StringUtils.isEmpty(meeting_period)||StringUtils.isEmpty(mtType)||StringUtils.isEmpty(attendance_people)||
                StringUtils.isEmpty(meeting_money)||StringUtils.isEmpty(is_net_meeting)||StringUtils.isEmpty(apply_unit)||StringUtils.isEmpty(apply_unit_name)||
                StringUtils.isEmpty(apply_user)||StringUtils.isEmpty(apply_user_name)){
            flag=false;
            return flag;
        }else{
            MeetingInfo meetingInfo=new MeetingInfo();
            meetingInfo.setUuid(new GUID2().toString36bit());
            meetingInfo.setSubject(subject);
            meetingInfo.setContent(content);
            meetingInfo.setPlace(place);
            meetingInfo.setStatus("0");
            meetingInfo.setStartDate(start_date);
            meetingInfo.setMeetingPeriod(meeting_period);
            meetingInfo.setMttype(mtType);
            meetingInfo.setAttendancePeoplePlan(attendance_people);
            meetingInfo.setMeetingMoney(meeting_money);
            meetingInfo.setIsNetMeeting(is_net_meeting);
            meetingInfo.setApplyUnit(apply_unit);
            meetingInfo.setApplyUnitName(apply_unit_name);
            meetingInfo.setApplyUser(apply_user);
            meetingInfo.setApplyUserName(apply_user_name);
            meetingInfo.setCreateTime(DateTools.getServerDateTime(10));
            meetingInfo.setIsDelete(0);
            try {
                meetingInfoMapper.insertSelective(meetingInfo);
            } catch (Exception e) {
                flag=false;
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        return flag;
    }
    public List<MeetingInfo> queryMeetList(String apply_unit, String subject, String start_date, String end_date){
        List<MeetingInfo> infoList=null;
        MeetingInfoExample meetingInfoExample=new MeetingInfoExample();
        MeetingInfoExample.Criteria meetingInfoCriteria=meetingInfoExample.createCriteria();
        meetingInfoCriteria.andIsDeleteEqualTo(0);
        //根据单位id
        if(!StringUtils.isEmpty(apply_unit)){
            meetingInfoCriteria.andApplyUnitEqualTo(apply_unit);
        }
        //主题模糊查询
        if(!StringUtils.isEmpty(subject)){
            meetingInfoCriteria.andSubjectLike("%"+subject+"%");
        }
        //时间跨度判定 大于等于输入的开始时间，小于等于结束时间
        infoList=meetingInfoMapper.selectByExample(meetingInfoExample);
        //删除不符合规则的
        Iterator<MeetingInfo> iter = infoList.iterator();
        while (iter.hasNext()) {
            MeetingInfo item = iter.next();
            if(!StringUtils.isEmpty(start_date)){
                int startFlag=compareDates(start_date,item.getStartDate());
                if(startFlag==0){
                    return null;
                }else if(startFlag==1){
                    iter.remove();
                }
            }
            if(!StringUtils.isEmpty(end_date)){
                int endFlag=compareDates(end_date,item.getStartDate());
                if(endFlag==0){
                    return null;
                }else if(endFlag==2){
                    iter.remove();
                }
            }
        }
        return infoList;
    }
    public Map<String,Object> queryMeetInfo(String meeting_id){
        Map<String,Object> backMap=new HashMap<>();
        if(StringUtils.isEmpty(meeting_id)){
            return null;
        }else{
            MeetingInfo meetingInfo=getMeetingById(meeting_id);
            if(StringUtils.isEmpty(meetingInfo)){
                return null;
            }else{
                //判断会议是否已经生产二维码，如果生成就返回人员信息,否则就返回会议详情和文件信息(如果有的话)
                String QRCode=meetingInfo.getQrCode();
                if(!StringUtils.isEmpty(QRCode)){
                    //返回签到人员信息
                    SignInfoExample signInfoExample=new SignInfoExample();
                    signInfoExample.or().andMainIdEqualTo(meeting_id);
                    List<SignInfo> signInfos=signInfoMapper.selectByExample(signInfoExample);
                    backMap.put("MeetingSignInfo",signInfos);
                }else {
                    //返回会议信息和会议问价信息
                    backMap.put("MeetingInfo",meetingInfo);
                    MeetingFileExample fileExample=new MeetingFileExample();
                    fileExample.or().andIsDeleteEqualTo(0).andMainIdEqualTo(meeting_id);
                    if(fileMapper.countByExample(fileExample)>0){
                        MeetingFile meetingFile=fileMapper.selectByExample(fileExample).get(0);
                        backMap.put("MeetingFile",meetingFile);
                    }
                }
            }
        }
        return backMap;
    }
    public Boolean deleteInfo(String meeting_id,String delete_user){
        Boolean flag=true;
        //所传参数不能为空
        if(StringUtils.isEmpty(meeting_id)||StringUtils.isEmpty(delete_user)){
            flag=false;
        }else{
            MeetingInfo meetingInfo=getMeetingById(meeting_id);
            //所传的会议号id是否可以查询到指定的会议
            if(StringUtils.isEmpty(meetingInfo)){
                flag=false;
            }else{
                //确认删除 删除条件1.删除人必须为会议的创建人2.不可删除已经生成了二维码的会议
                if(
                    delete_user.equals(meetingInfo.getCreateUser())
                    &&StringUtils.isEmpty(meetingInfo.getQrCode())
                ){
                    meetingInfo.setIsDelete(1);
                    meetingInfoMapper.updateByPrimaryKeySelective(meetingInfo);
                }else{
                    flag=false;
                }
            }
        }
        return flag;
    }
    //判断两个时间的先后
    public int compareDates(String d1,String d2)
    {
        int flag=0;
        try{
            // If you already have date objects then skip 1

            //1
            // Create 2 dates starts
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date1 = sdf.parse(d1);
            Date date2 = sdf.parse(d2);

            System.out.println("Date1"+sdf.format(date1));
            System.out.println("Date2"+sdf.format(date2));System.out.println();

            // Create 2 dates ends
            //1

            // Date object is having 3 methods namely after,before and equals for comparing
            // after() will return true if and only if date1 is after date 2
            if(date1.after(date2)){
                flag=1;
                return flag;
            }
            // before() will return true if and only if date1 is before date2
            if(date1.before(date2)){
                flag=2;
                return flag;
            }

            //equals() returns true if both the dates are equal
            if(date1.equals(date2)){
                flag=3;
                return flag;
            }
        }
        catch(ParseException ex){
            ex.printStackTrace();
            return flag;
        }
        return flag;
    }
    public JSONObject getUserJsonFormUrl(String callback_url) throws IOException,JSONException {
        //url解密
        String url= URLDecoder.decode(callback_url, "utf-8");
        InputStream is = new URL(url).openStream();
        try {
            BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
            String jsonText = readAll(rd);
            JSONObject json = JSONObject.fromObject(jsonText);
            return json;
        } finally {
            is.close();
        }
    }
    @Transactional
    public Boolean scanCode(String meeting_id,String sign_user,String sign_user_name){
        Boolean flag=true;
        //会议id验证
        MeetingInfo meetingInfo=getMeetingById(meeting_id);
        if(StringUtils.isEmpty(meetingInfo)){
            flag=false;
        }else{
            //传参不为空判定
            if(StringUtils.isEmpty(sign_user)||StringUtils.isEmpty(sign_user_name)||(!("2").equals(meetingInfo.getStatus()))){
                flag=false;
            }else{
                //插入人员
                SignInfo signInfo=new SignInfo();
                signInfo.setUuid(new GUID2().toString36bit());
                signInfo.setMainId(meeting_id);
                signInfo.setSignTime(DateTools.getServerDateTime(10));
                signInfo.setSignUser(sign_user);
                signInfo.setSignUserName(sign_user_name);
                signInfoMapper.insertSelective(signInfo);
            }
        }
        return flag;
    }
    public Boolean FileUpload(String meeting_id, MultipartFile Files[],String type,String create_user){
        Boolean flag=true;
        //会议id验证
        MeetingInfo meetingInfo=getMeetingById(meeting_id);
        if(StringUtils.isEmpty(meetingInfo)){
            flag=false;
        }else{
            //传参不为空判定
            if(StringUtils.isEmpty(Files)||((!("1").equals(type))&&(!("2").equals(type)))||StringUtils.isEmpty(create_user)){
                flag=false;
            }else{
                //修改会议的状态为完结
                meetingInfo.setStatus("2");
                meetingInfoMapper.updateByPrimaryKeySelective(meetingInfo);
                //将文件上传至本地
                String path = Constants.tomcatUrl + "/resources/upload/";
                File UploadFolder = new File(path + "/meetingFile");//meetingFile: 上传的会议文件夹
                //判断文件夹是否存在，不存在就创建
                if (!UploadFolder.exists() && !UploadFolder.isDirectory()) {
                    UploadFolder.mkdirs();
                }
                try {
                    InputStream inputStream=null;
                    OutputStream outputStream=null;;
                    for(MultipartFile file:Files){
                        /***************文件读取并下载到本地***************/
                        MeetingFile meetingFile=new MeetingFile();
                        inputStream = file.getInputStream();
                        //获取文件后缀名
                        String FileName=file.getOriginalFilename();//所传文件的名称
                        String prefix = FileName.substring(FileName.lastIndexOf(".") + 1);//截取文件后缀
                        //生成新的文件名称=日期+uuid
                        String localFileName=DateTools.getServerDateTime(9)+"_"+(new GUID2().toString36bit())+"."+prefix;
                        File targetFile = new File(path + "/meetingFile/" + localFileName);
                        outputStream = new FileOutputStream(targetFile);
                        FileCopyUtils.copy(inputStream, outputStream);
                        /***************文件读取并下载到本地***************/

                        //插入数据到数据库中
                        meetingFile.setUuid(new GUID2().toString36bit());
                        meetingFile.setMainId(meeting_id);
                        meetingFile.setType(type);
                        meetingFile.setFileName(FileName);
                        meetingFile.setDownloadUrl("/upload/meetingFile/" + localFileName);
                        meetingFile.setCreateUser(create_user);
                        meetingFile.setCreateTime(DateTools.getServerDateTime(10));
                        meetingFile.setIsDelete(0);
                        fileMapper.insertSelective(meetingFile);
                    }
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }
    public List<SignInfo> queryAllSignedPersons(String meeting_id){
        SignInfoExample signInfoExample=new SignInfoExample();
        signInfoExample.or().andMainIdEqualTo(meeting_id);
        List<SignInfo> signInfos=signInfoMapper.selectByExample(signInfoExample);
        return signInfos;
    }
    public List<MeetingFile> queryMeetingFileByMeetingIdOrFileNameOrType(String meeting_id,String type,String file_name){
        MeetingFileExample meetingFileExample=new MeetingFileExample();
        MeetingFileExample.Criteria fileCriteria=meetingFileExample.createCriteria();
        fileCriteria.andMainIdEqualTo(meeting_id);
        if(!StringUtils.isEmpty(type)){
            fileCriteria.andTypeEqualTo(type);
        }
        if(!StringUtils.isEmpty(file_name)){
            fileCriteria.andFileNameLike("%"+file_name+"%");
        }
        List<MeetingFile> fileList=fileMapper.selectByExample(meetingFileExample);
        return fileList;
    }
    public String deleteFile(String meeting_id,String create_user){
        String result="success";
        MeetingFileExample meetingFileExample=new MeetingFileExample();
        meetingFileExample.or().andIsDeleteEqualTo(0).andMainIdEqualTo(meeting_id).andCreateUserEqualTo(create_user);
        if(fileMapper.countByExample(meetingFileExample)==0){
            result="false";
        }else{
            MeetingFile meetingFile=fileMapper.selectByExample(meetingFileExample).get(0);
            if(create_user.equals(meetingFile.getCreateUser())){
                meetingFile.setIsDelete(1);
                fileMapper.updateByPrimaryKeySelective(meetingFile);
            }else{
                result="false";
            }
        }
        return result;
    }
    @Transactional
    public String getSecretKey(String appKey,String secretKey,String requestTime){
        String result="false";
        if((Constants.APP_KEY.equals(appKey)&&(Constants.SECRET_KEY.equals(secretKey)))){
            String key=appKey+secretKey+requestTime;
            String requestSecretKey= Md5Util.MD5(key);
            result=requestSecretKey;
            //插入签名信息至数据库中
            Key keyObject=new Key();
            keyObject.setAppKey(appKey);
            keyObject.setRequestKey(result);
            keyObject.setRequestTime(requestTime);
            keyObject.setSecretKey(secretKey);
            try {
                keyMapper.insertSelective(keyObject);
                CacheManager.put(appKey,keyObject,10, TimeUnit.MINUTES);
            } catch (Exception e) {
                e.printStackTrace();
                result="error";
                return result;
            }
        }else{
            return result;
        }
        return result;
    }
    public String verifyKeyIsTrue(String appKey,String requestKey){
        String result="success";
        //查找缓存中存储的秘钥信息，如果信息已经存在，进行校验，否则返回过期
        Cache keyObjectInCache= null;
        try {
            keyObjectInCache = CacheManager.get(appKey);
            if(StringUtils.isEmpty(keyObjectInCache)){
                result="overDue";//过期
            }else{
                //验证requestKey信息是否正确
                Key key=keyObjectInCache.getValue();
                if(!key.getRequestKey().equals(requestKey)){
                    result="false";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result="false";
            return result;
        }
        return result;
    }
    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }
}
